package com.ys.otms.services.impl;


import com.github.wxpay.sdk.WXPay;
import com.ys.otms.dao.IBillsDao;
import com.ys.otms.dao.IDeductionsDao;
import com.ys.otms.dto.BillsDto;
import com.ys.otms.dto.LeftAmountDto;
import com.ys.otms.dto.ParamDto;
import com.ys.otms.services.IDeductionsServices;
import com.ys.otms.services.IPayServices;
import com.ys.otms.utils.DateUtil;
import com.ys.otms.utils.HttpUtil;
import com.ys.otms.utils.JsonUtil;
import com.ys.otms.utils.SessionUtil;
import com.ys.otms.wxUtils.WXConfig;

import com.ys.otms.wxUtils.WXPayConstants;
import com.ys.otms.wxUtils.WXPayUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.*;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Administrator on 2018/9/18.
 */
@Service
public class PayServiceImpl implements IPayServices {

    private static Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private IDeductionsDao iDeductionsDao;

    @Autowired
    private IBillsDao iBillsDao;

    /**
     * 获取本机IP地址
     * @author chenp
     * @return
     */
    public static String localIp(){
        String ip = null;
        Enumeration allNetInterfaces;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                List<InterfaceAddress> InterfaceAddress = netInterface.getInterfaceAddresses();
                for (InterfaceAddress add : InterfaceAddress) {
                    InetAddress Ip = add.getAddress();
                    if (Ip != null && Ip instanceof Inet4Address) {
                        ip = Ip.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            logger.warn("获取本机Ip失败:异常信息:"+e.getMessage());
        }
        return ip;
    }


    @Override
    public JSONObject toWXPay(HttpServletRequest request, HttpServletResponse response) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("PayServiceImpl toWXPay start obj{}",obj);
        //金额
        String total_fee = JsonUtil.getJSONObjectString(obj,"money");
        //订单号
        //(String)request.getSession().getAttribute("SESSION_COMPANY_ID")
        String out_trade_no = "wx"+DateUtil.getCurrentDateStr()+"-"+(String) request.getSession().getAttribute("SESSION_COMPANY_ID");
        String body = "汇找船余额充值";
        String sign_type ="MD5";
        Map<String,String> packageParams = new HashMap<String,String>();
        WXConfig wxConfig = new WXConfig();
        WXPay wxPay = new WXPay(wxConfig);
        packageParams.put("appid",wxConfig.getAppID());
        packageParams.put("mch_id",wxConfig.getMchID());
        packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
        packageParams.put("sign_type",sign_type);
        packageParams.put("body",body);
        packageParams.put("out_trade_no",out_trade_no);
        packageParams.put("total_fee",String.valueOf(Integer.parseInt(total_fee)*100));
        packageParams.put("trade_type","NATIVE");
        packageParams.put("notify_url",WXConfig.NOTIFY_URL);
        packageParams.put("spbill_create_ip",localIp());
        packageParams.put("sign",WXPayUtil.generateSignature(packageParams,wxConfig.getKey()));
        String requestXML = WXPayUtil.mapToXml(packageParams);
        logger.info("requestXML："+requestXML);
        Map<String,String> resp  =wxPay.unifiedOrder(packageParams) ;
        logger.info("resp："+resp);
        BillsDto billsDto =new BillsDto();
        JSONObject jsonObject = new JSONObject();
        if ("SUCCESS".equals(resp.get("return_code"))){
            billsDto.setBillsStatus(0);
            billsDto.setBillsTime(new Timestamp((new Date()).getTime()));
            billsDto.setBillsType("1");
            billsDto.setMoney(total_fee);
            billsDto.setOrdernumber(out_trade_no);
            billsDto.setUserId(Integer.parseInt((String) request.getSession().getAttribute("SESSION_USER_ID")));
            billsDto.setCompanyId(Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID")));
            logger.info("billsDto："+billsDto);
            iBillsDao.insertBills(billsDto);
            String code_url = resp.get("code_url");
            jsonObject.put("code_url",code_url);
            jsonObject.put("out_trade_no",out_trade_no);
            jsonObject.put("SUCCESS",true);
        }else{
            jsonObject.put("MSG",resp.get("return_msg"));
            jsonObject.put("SUCCESS",false);
        }
        return jsonObject;
    }

    @Override
    public JSONObject selectLeftAmount(HttpServletRequest request) throws Exception {
        ParamDto paramDto = new ParamDto();
       // paramDto.setUserId(1);
       paramDto.setUserId(Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID")));
        LeftAmountDto leftAmountDto = iDeductionsDao.selectLeftAmountByCompanyId(paramDto);
        JSONObject jsonObject = new JSONObject();
        if (leftAmountDto == null){
            jsonObject.put("leftAmount",0);
        }else{
            jsonObject.put("leftAmount",leftAmountDto.getLeftAmount());
        }
        jsonObject.put("SUCCESS",true);
        return jsonObject;
    }

    @Override
    public JSONObject wxNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("微信支付回调数据开始");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream ouStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            ouStream.write(buffer, 0, len);
        }
        String notifyData = new String(ouStream.toByteArray(), "utf-8");
        inStream.close();
        ouStream.close();
        logger.info("接收到的报文：" + notifyData);
        Map<String,String> notifyMap = WXPayUtil.xmlToMap(notifyData);
        WXConfig wxConfig = new WXConfig();
        WXPay wxpay = new WXPay(wxConfig);
        ParamDto paramDto = new ParamDto();
        JSONObject jsonObject = new JSONObject();
        if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
            if ("SUCCESS".equals(notifyMap.get("return_code")) && "SUCCESS".equals(notifyMap.get("result_code"))){
                paramDto.setState(1);
                paramDto.setOrderNum(notifyMap.get("out_trade_no"));
                logger.info("paramDto====================="+paramDto);
                iBillsDao.updateBillsByStatus(paramDto);
                BillsDto billsDto = iBillsDao.selectBillsByOrdernumber(paramDto);
                paramDto.setUserId(billsDto.getCompanyId());
                LeftAmountDto leftAmount = new LeftAmountDto();
                LeftAmountDto leftAmountDto = iDeductionsDao.selectLeftAmountByCompanyId(paramDto);
                leftAmount.setCompanyId(billsDto.getCompanyId());
                if (leftAmountDto ==null){
                    leftAmount.setLeftAmount(Double.parseDouble(billsDto.getMoney()));
                    iDeductionsDao.insertLeftAmount(leftAmount);
                }else{
                    leftAmount.setLeftAmount(leftAmountDto.getLeftAmount()+Double.parseDouble(billsDto.getMoney()));
                    logger.info("xxxxxxxxxxxxxx"+leftAmount);
                    iDeductionsDao.updateLeftAmountMoney(leftAmount);
                }
                jsonObject.put("SUCCESS",true);
                String returnStr = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                response.getWriter().write(returnStr);
            }else{
                String returnStr = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>";
                response.getWriter().write(returnStr);
                return null;
            }
        }
      return jsonObject;
    }

    @Override
    public JSONObject selectWxOrder(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("PayServiceImpl toWXPay start obj{}",obj);
        String out_trade_no = JsonUtil.getJSONObjectString(obj,"out_trade_no");
        Map<String,String> packageParams = new HashMap<String,String>();
        WXConfig wxConfig = new WXConfig();
        WXPay wxPay = new WXPay(wxConfig);
        packageParams.put("appid",wxConfig.getAppID());
        packageParams.put("mch_id",wxConfig.getMchID());
        packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
        packageParams.put("out_trade_no",out_trade_no);
        packageParams.put("sign",WXPayUtil.generateSignature(packageParams,wxConfig.getKey()));
        String requestXML = WXPayUtil.mapToXml(packageParams);
        logger.info("requestXML："+requestXML);
        Map<String,String> respOrder = wxPay.orderQuery(packageParams);
        logger.info("respOrder====================="+respOrder);
        JSONObject jsonObject = new JSONObject();
        if ("SUCCESS".equals(respOrder.get("return_code")) && "SUCCESS".equals(respOrder.get("result_code"))){
            jsonObject.put("SUCCESS",true);
            jsonObject.put("trade_state",respOrder.get("trade_state"));
        }else{
            jsonObject.put("SUCCESS",false);
            jsonObject.put("return_code",respOrder.get("return_code"));
        }
        return jsonObject;
    }

}
